/**
 * GameEngine - 核心游戏引擎类
 * 负责Canvas初始化、游戏循环、渲染和更新逻辑
 */

import { EntityManager, type EntityManagerOptions } from './EntityManager'
import { CollisionDetector, type CollisionDetectorOptions } from './CollisionDetector'
import { InputManager, type InputManagerOptions, InputAction } from './InputManager'
import { Player } from './Player'

export interface Vector2D {
  x: number
  y: number
}

export interface GameEngineOptions {
  canvasId: string
  width?: number
  height?: number
  targetFPS?: number
  entityManagerOptions?: EntityManagerOptions
  collisionDetectorOptions?: CollisionDetectorOptions
  inputManagerOptions?: InputManagerOptions
}

export class GameEngine {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D
  private entityManager: EntityManager
  private collisionDetector: CollisionDetector
  private inputManager: InputManager
  private isRunning: boolean = false
  private isPaused: boolean = false
  private lastFrameTime: number = 0
  private targetFPS: number
  private frameInterval: number
  private animationFrameId: number | null = null
  
  // 简化的背景渲染
  private backgroundOffset: number = 0
  private backgroundSpeed: number = 50

  constructor(options: GameEngineOptions) {
    const canvas = document.getElementById(options.canvasId) as HTMLCanvasElement
    if (!canvas) {
      throw new Error(`Canvas element with id "${options.canvasId}" not found`)
    }

    this.canvas = canvas
    const context = canvas.getContext('2d')
    if (!context) {
      throw new Error('Failed to get 2D rendering context')
    }

    this.ctx = context
    this.targetFPS = options.targetFPS || 60
    this.frameInterval = 1000 / this.targetFPS

    // 设置Canvas尺寸
    this.canvas.width = options.width || 800
    this.canvas.height = options.height || 400

    // 初始化EntityManager
    this.entityManager = new EntityManager(options.entityManagerOptions)

    // 初始化CollisionDetector
    this.collisionDetector = new CollisionDetector(options.collisionDetectorOptions)

    // 初始化InputManager
    this.inputManager = new InputManager({
      element: this.canvas,
      ...options.inputManagerOptions
    })

    // 设置输入处理器
    this.setupInputHandlers()

    // 初始化Canvas样式
    this.initializeCanvas()

    console.log('游戏引擎初始化完成')
  }

  /**
   * 初始化Canvas设置
   */
  private initializeCanvas(): void {
    this.ctx.imageSmoothingEnabled = true
    this.ctx.textAlign = 'left'
    this.ctx.textBaseline = 'top'
  }

  /**
   * 设置输入处理器
   */
  private setupInputHandlers(): void {
    this.inputManager.addHandler((action: InputAction, pressed: boolean) => {
      if (!pressed) return // 只处理按键按下事件

      // 获取玩家实体
      const player = this.getPlayer()
      if (!player) return

      switch (action) {
        case InputAction.JUMP:
          player.jump()
          break
        case InputAction.SLIDE:
          player.slide()
          break
        case InputAction.MOVE_LEFT:
          player.moveLeft()
          break
        case InputAction.MOVE_RIGHT:
          player.moveRight()
          break
        case InputAction.PAUSE:
          this.togglePause()
          break
      }
    })
  }

  /**
   * 获取玩家实体
   */
  private getPlayer(): Player | null {
    const entities = this.entityManager.getAllEntities()
    const player = entities.find(entity => entity instanceof Player) as Player
    return player || null
  }

  /**
   * 切换暂停状态
   */
  private togglePause(): void {
    if (this.isPaused) {
      this.resume()
    } else {
      this.pause()
    }
  }

  /**
   * 启动游戏引擎
   */
  start(): void {
    if (this.isRunning) {
      console.warn('GameEngine is already running')
      return
    }

    this.isRunning = true
    this.isPaused = false
    this.lastFrameTime = performance.now()
    this.gameLoop()
  }

  /**
   * 暂停游戏
   */
  pause(): void {
    this.isPaused = true
  }

  /**
   * 恢复游戏
   */
  resume(): void {
    if (!this.isRunning) {
      console.warn('Cannot resume: GameEngine is not running')
      return
    }
    
    this.isPaused = false
    this.lastFrameTime = performance.now()
  }

  /**
   * 停止游戏引擎
   */
  stop(): void {
    this.isRunning = false
    this.isPaused = false
    
    if (this.animationFrameId !== null) {
      cancelAnimationFrame(this.animationFrameId)
      this.animationFrameId = null
    }
  }

  /**
   * 游戏主循环
   */
  private gameLoop(): void {
    if (!this.isRunning) {
      return
    }

    const currentTime = performance.now()
    const deltaTime = currentTime - this.lastFrameTime

    // 控制帧率
    if (deltaTime >= this.frameInterval) {
      if (!this.isPaused) {
        this.update(deltaTime)
        this.render()
      }
      this.lastFrameTime = currentTime - (deltaTime % this.frameInterval)
    }

    this.animationFrameId = requestAnimationFrame(() => this.gameLoop())
  }

  /**
   * 更新游戏逻辑
   * @param deltaTime 距离上一帧的时间差（毫秒）
   */
  update(deltaTime: number): void {
    // 更新背景滚动
    this.backgroundOffset += this.backgroundSpeed * (deltaTime / 1000)
    
    // 更新所有实体
    this.entityManager.updateAll(deltaTime)
    
    // 执行碰撞检测
    const activeEntities = this.entityManager.getAllEntities().filter(entity => entity.active)
    this.collisionDetector.detectCollisions(activeEntities)
  }

  /**
   * 渲染游戏画面
   */
  render(): void {
    try {
      // 清空画布
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
      
      // 渲染简化背景
      this.renderBackground()
      
      // 渲染所有实体
      this.entityManager.renderAll(this.ctx)
      
    } catch (error) {
      console.error('渲染错误:', error)
      this.pause()
    }
  }

  /**
   * 渲染简化背景
   */
  private renderBackground(): void {
    // 渲染天空渐变背景
    const gradient = this.ctx.createLinearGradient(0, 0, 0, this.canvas.height)
    gradient.addColorStop(0, '#87CEEB') // 天蓝色
    gradient.addColorStop(1, '#98FB98') // 浅绿色
    
    this.ctx.fillStyle = gradient
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)
    
    // 渲染滚动的云朵效果
    this.ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'
    const cloudY = this.canvas.height * 0.2
    const cloudSpacing = 200
    const numClouds = Math.ceil(this.canvas.width / cloudSpacing) + 2
    
    for (let i = 0; i < numClouds; i++) {
      const cloudX = (i * cloudSpacing - this.backgroundOffset) % (this.canvas.width + cloudSpacing)
      this.renderCloud(cloudX, cloudY)
    }
    
    // 渲染地面
    this.ctx.fillStyle = '#8B4513' // 棕色地面
    const groundY = this.canvas.height * 0.8
    this.ctx.fillRect(0, groundY, this.canvas.width, this.canvas.height - groundY)
  }

  /**
   * 渲染云朵
   */
  private renderCloud(x: number, y: number): void {
    this.ctx.beginPath()
    this.ctx.arc(x, y, 20, 0, Math.PI * 2)
    this.ctx.arc(x + 25, y, 25, 0, Math.PI * 2)
    this.ctx.arc(x + 50, y, 20, 0, Math.PI * 2)
    this.ctx.arc(x + 25, y - 15, 15, 0, Math.PI * 2)
    this.ctx.fill()
  }

  /**
   * 获取Canvas元素
   */
  getCanvas(): HTMLCanvasElement {
    return this.canvas
  }

  /**
   * 获取渲染上下文
   */
  getContext(): CanvasRenderingContext2D {
    return this.ctx
  }

  /**
   * 获取Canvas尺寸
   */
  getSize(): { width: number; height: number } {
    return {
      width: this.canvas.width,
      height: this.canvas.height
    }
  }

  /**
   * 检查游戏是否正在运行
   */
  isGameRunning(): boolean {
    return this.isRunning && !this.isPaused
  }

  /**
   * 检查游戏是否暂停
   */
  isGamePaused(): boolean {
    return this.isPaused
  }

  /**
   * 设置目标FPS
   */
  setTargetFPS(fps: number): void {
    this.targetFPS = Math.max(1, Math.min(120, fps)) // 限制在1-120之间
    this.frameInterval = 1000 / this.targetFPS
  }

  /**
   * 获取当前FPS
   */
  getCurrentFPS(): number {
    return this.targetFPS
  }

  /**
   * 获取实体管理器
   */
  getEntityManager(): EntityManager {
    return this.entityManager
  }

  /**
   * 获取碰撞检测器
   */
  getCollisionDetector(): CollisionDetector {
    return this.collisionDetector
  }

  /**
   * 获取输入管理器
   */
  getInputManager(): InputManager {
    return this.inputManager
  }

  /**
   * 设置背景滚动速度
   */
  setBackgroundScrollSpeed(speed: number): void {
    this.backgroundSpeed = speed
  }

  /**
   * 重置背景位置
   */
  resetBackground(): void {
    this.backgroundOffset = 0
  }

  /**
   * 添加玩家到游戏中
   */
  addPlayer(player: Player): void {
    this.entityManager.addEntity(player)
  }

  /**
   * 清理所有游戏数据
   */
  cleanup(): void {
    this.entityManager.clear()
    this.inputManager.destroy()
    this.backgroundOffset = 0
  }
}